import axios from '@/utils/request/axios';
import { WxMsgRecord } from 'common/src/apis';
import { getKtsFromMPerSec } from 'common/src/utils/weather';

export class GetTaskListParams {
  page: number;
  length: number;
}

export class RoutePoint {
  lat: number;
  lon: number;
  /** 秒时间戳 */
  ts: number;
  /** 航向角 */
  cog: number;
  sog: number;
  /** 关键点 */
  isMajor: boolean;
}

export class RouteAttitude {
  lat: number;
  lon: number;
  roll_pred: number;
  pitch_pred: number;
  /** 2025/01/01 16:44:14 */
  time: string;
  /** 航向角 */
  course: number;
  /** 转向角 */
  dif_course: number;
  /** 波周期 s */
  mwp: number;
  /** 浪夹角 */
  relative_wave_dir: number;
  /** 船速 */
  speed: number;
  /** 有效波高 m */
  swh: number;
  /** 10米风西风 m/s */
  u10: number;
  /** 10米风北风 m/s */
  v10: number;
  /** 风速 m/s */
  wind_speed: number;
  /** 流速 m/s */
  flow_speed: number;
  /** 西向流 m/s */
  utotal: number;
  /** 北向流 m/s */
  vtotal: number;
  /** 累计横向位移 */
  totalDrift: number;
}

export class TaskItem {
  id: number;
  mmsi: string;
  name: string;
  ptdUtc: string;
  taskStage: number;
  /** 经纬度列表，按顺序 */
  points: {
    /** 经度 */
    longitude: number;
    /** 纬度 */
    latitude: number;
    id: number | null;
    name?: string;
  }[];
  /** 自定义经纬度列表，按顺序 */
  diyPoints?: {
    /** 经度 */
    longitude: number;
    /** 纬度 */
    latitude: number;
  }[];
  routeType: number[];
  /** 111 第一位最快路径 第二位安全 第三位固定时间 1表示已完成 0表示进行中 */
  routeStatus: number;
  /** 111 第一位最快路径 第二位安全 第三位固定时间 1表示错误 0表示正常 */
  pathStatus: number;
  routes: Record<number, RoutePoint[]>;
  /** 航行速度 */
  sog: number;
  /** 空间精度 20,40,80 默认20 */
  mapScale: number;
  /** 最大风速 */
  windSpeed?: number;
  /** 最大浪高 */
  waveHeight?: number;
  /** 左上角纬度 */
  taskLtLatitude?: number;
  /** 左上角经度 */
  taskLtLongitude?: number;
  /** 右下角纬度 */
  taskRbLatitude?: number;
  /** 右下角经度 */
  taskRbLongitude?: number;
  /** 预警风速 */
  alertWindSpeed?: number;
  /** 预警浪高 */
  alertWaveHeight?: number;
  /** 固定时间航线预计到达时间 */
  eta?: string;
  /** 固定时间到达允许误差(秒) */
  tolerance?: number;
  comment: string;
  /** 横摇 */
  roll: number;
  /** 纵摇 */
  pitch: number;
}

export async function getTaskList(params: GetTaskListParams) {
  const res = await axios({
    method: 'get',
    url: `/voyage/list`,
    params,
  });
  return {
    list: res.data.data.list as TaskItem[],
    total: res.data.data.total || 0,
  };
}

export class TaskPoseReturn {
  poses?: Record<number, RouteAttitude[]>;
}

export async function getTaskPose(id: number) {
  const res = await axios({
    method: 'get',
    url: `/pose/${id}`,
  });
  return (res.data?.data || {}) as TaskPoseReturn;
}

export class GetPointPoseParams {
  /** 船速 kts */
  sog?: number;
  /** ts 秒时间戳 */
  ts: number;
  /** 经度 */
  lon: number;
  /** 纬度 */
  lat: number;
}

export async function getPointPose(params: GetPointPoseParams) {
  const res = await axios({
    method: 'get',
    url: '/pose/eight/angle',
    params,
  });
  return (res.data?.data || []) as RouteAttitude[];
}

export async function getPointClimatic(params: GetPointPoseParams) {
  const res = await axios({
    method: 'get',
    url: '/task/weather/rate',
    params,
  });
  return res.data ;
}


interface GetTaskDetailParams {
  id: number;
}

export async function getTaskDetail(params: GetTaskDetailParams) {
  const res = await axios({
    method: 'get',
    url: `/voyage/get`,
    params,
  });
  return res.data;
}

export class EditTaskData {
  /** 船号 */
  mmsi: string;
  /** 名称 */
  name: string;
  /** 任务阶段: 1-任务筹划导航图;2-出航筹备导航图;3-战备航渡导航图;4-战术航海导航图 */
  taskStage: number;
  /** 预计开航时间 */
  ptdUtc: string;
  /** 航行速度 */
  sog: Number;
  /** 经纬度列表，按顺序 */
  points: {
    /** 经度 */
    longitude: number;
    /** 纬度 */
    latitude: number;
    id: number | null;
    name?: string;
  }[];
  diyPoints: {
    /** 经度 */
    longitude: number;
    /** 纬度 */
    latitude: number;
  }[];
  /** 航线类型 */
  routeType: number[];
  /** 安全评估 */
  safetyRating: number;
  /** 左上角纬度 */
  taskLtLatitude?: number;
  /** 左上角经度 */
  taskLtLongitude?: number;
  /** 右下角纬度 */
  taskRbLatitude?: number;
  /** 右下角经度 */
  taskRbLongitude?: number;
  // /** 最大风速 */
  // windSpeed?: number;
  // /** 最大浪高 */
  // waveHeight?: number;
  /** 预警风速 */
  alertWindSpeed?: number;
  /** 预警浪高 */
  alertWaveHeight?: number;
  /** 固定时间航线预计到达时间 */
  eta?: string;
  /** 固定时间到达允许误差(秒) */
  tolerance?: number;
  /** 空间精度 20,40,80 默认20 */
  mapScale?: number;
  /** 备注 */
  comment?: string;
  /** 横摇 */
  roll?: number;
  /** 纵摇 */
  pitch?: number;
}

export async function addTask(data: EditTaskData) {
  const res = await axios({
    method: 'post',
    url: '/voyage/save',
    data,
  });
  return res.data;
}

export async function editTask(id: number, data: EditTaskData) {
  const res = await axios({
    method: 'put',
    url: `/voyage/edit/${id}`,
    data,
  });
  return res.data;
}

export class EditTaskRouteData {
  tid: number;
  type: number;
  points: RoutePoint[];
}

export async function editTaskRoute(data: EditTaskRouteData) {
  const res = await axios({
    method: 'post',
    url: `/task/route/edit`,
    data,
  });
  return res.data;
}

export class DeleteTaskData {
  /** 可批量，逗号分割 */
  ids: string;
}

/** 删除任务 */
export async function deleteTask(data: DeleteTaskData) {
  const res = await axios({
    method: 'post',
    url: '/voyage/delete',
    data,
  });
  return res.data;
}

export class RegionCustomRouteData {
  /** 任务id */
  tid: number;
  /** 速度 */
  sog: number;
  /** 出发时间 */
  etd: string;
  /** 航线名称 */
  name: string;
  /** 点位 */
  points: {
    ts: number;
    lon: number;
    lat: number;
    cog: number;
    sog: number;
  }[];
}

/** 区域新增自定义航线 */
export async function addRegionCustomRoute(data: RegionCustomRouteData) {
  const res = await axios({
    method: 'post',
    url: '/task/ship/route/add',
    data,
  });
  return res.data;
}

/** 区域编辑自定义航线 */
export async function editRegionCustomRoute(index: number, data: RegionCustomRouteData) {
  const res = await axios({
    method: 'post',
    url: '/task/ship/route/edit',
    data: { index, ...data },
  });
  return res.data;
}

/** 区域删除非自定义航线 */
export async function deleteRegionOtherRoute(data: {
  /** 任务id */
  tid: number;
  /** 航线index */
  type: number;
}) {
  const res = await axios({
    method: 'post',
    url: '/task/route/delete',
    data,
  });
  return res.data;
}

/** 区域删除自定义航线 */
export async function deleteRegionCustomRoute(data: {
  /** 任务id */
  tid: number;
  /** 航线index */
  index: number;
}) {
  const res = await axios({
    method: 'post',
    url: '/task/ship/route/delete',
    data,
  });
  return res.data;
}

export class CustomRoutePose extends RegionCustomRouteData {
  pose: RouteAttitude[];
}

/** 获取区域自定义航线及姿态 */
export async function getRegionCustomRoutePose(id: number) {
  const res = await axios({
    method: 'get',
    url: `/ship/route/${id}`,
  });
  return (res.data?.data?.shipRoutes || []) as CustomRoutePose[];
}

export class GetSafetyJudegeParams {
  /** 1：单因子；2：多因子 */
  factor: number;
  /** 单因子气象要素：1：风速；2：有效波高；3：波周期；4：流速；5：降水；6：能见度 */
  meteo?: number;
  /** 单因子特征向量：1：强值频率；2：概率极值；3：平均值；4：气候变化趋势 */
  feature: number;
  /** 概率极值的3个选项：p80：五年一遇；p90：十年一遇；p95：二十年一遇 */
  probability?: string;
  /** 强值高的等级：1-7对应7个等级 */
  maxLevel?: number;
  /** 强值低的等级：1-7对应7个等级 */
  minLevel?: number;
  /** 多因子算法：3：critic+物理；2：物理；1：critic */
  algorithm?: number;
  /** 船舶摇摆度数 critic对应的id */
  cid?: string;
  /** 物理约束 */
  vid?: string;
}

export class SafetyPoint {
  ts: number;
  cog: number;
  lat: number;
  lon: number;
  sog: number;
  dangerFactor: number;
}

export class SafetyJudgeData {
  route: SafetyPoint[];
  urlList: {
    month: string;
    decade: number;
    /** 秒时间戳 */
    ts: number;
    url: string;
  }[];
}

/** 获取安全评估结果 */
export async function getSafetyJudege(id: number, params: GetSafetyJudegeParams) {
  const res = await axios({
    method: 'get',
    url: `/safety/${id}`,
    params,
  });
  return res.data.data as SafetyJudgeData;
}

export class WarningPoint extends RoutePoint {
  warnInfo: {
    abj: {
      description: string;
      name: string;
      weatherContent: string;
    }[];
    wave: {
      seaWaveHeight: number;
      seaWaveDirection: string;
      seaWaveAngle: number;
    }[];
    wind: {
      knots: number;
      direction: string;
      angle: number;
    }[];
  }
}

export class WarningData {
  mmsi: string;
  alertWaveHeight:number;
  alertWindSpeed:number;
  taskStage:number;
  routes: Record<string, WarningPoint[]>;
}

/** 查询危险报文预警 */
export async function getWarningByTaskId(id: number) {
  const res = await axios({
    method: 'get',
    url: `/warn/${id}`,
  });
  return res.data.data as WarningData;
}

export class MultiFactorParams {
  /** 摇摆度数选项 */
  critic: {
    cid: string;
    name: string;
    value: {
      curDir: number;
      current: number;
      swDir: number;
      swh: number;
      swp: number;
      wind: number;
      windDir: number;
    };
  }[];
  /** 物理约束选项 */
  vis: {
    vid: string;
    name: string;
    value: {
      start: number;
      end: number;
    };
  }[];
}

/** 查询多因子参数 */
export async function getMultiFactorParams() {
  const res = await axios({
    method: 'get',
    url: '/multifactors/query-all',
    baseURL: '/area',
  });
  return res.data.data as MultiFactorParams;
}

export function getRollPitch(
  arr: RouteAttitude[],
  /** 毫秒时间戳 */
  time: number,
) {
  let index = 0;
  for (let point of arr) {
    if (new Date(point.time).valueOf() > time) {
      break;
    }
    if (index < arr.length - 1) {
      index++;
    }
  }
  const point = arr[index];
  const { roll_pred, pitch_pred, wind_speed, u10, v10, swh } = point;
  let windAngle = 0;
  const windSpd = typeof(wind_speed) === 'number' ? getKtsFromMPerSec(wind_speed) : undefined;
  if (typeof(wind_speed) === 'number' && typeof(u10) === 'number' && typeof(v10) === 'number') {
    let sinAngle = -u10 / wind_speed;
    let cosAngle = v10 / wind_speed;
    // + + 270~360 sin < 0 cos > 0
    // + - 180~270 sin < 0 cos < 0
    // - - 90~180 sin > 0 cos < 0
    // - + 0~90 sin > 0 cos > 0
    windAngle = Math.asin(sinAngle) / Math.PI * 180;
    if (cosAngle < 0) {
      if (windAngle > 0) {
        windAngle = 90 + (90 - windAngle);
      } else {
        windAngle = -90 - (windAngle + 90);
      }
    }
    if (windAngle < 0) {
      windAngle += 360;
    }
  }
  return {
    roll: roll_pred,
    pitch: pitch_pred,
    windSpd,
    windAngle,
    wave: swh,
  };
}

export function getSogCog(arr: {ts: number; sog: number, cog: number}[], time: number) {
  let index = 0;
  for (let point of arr) {
    if (point.ts * 1000 > time) {
      break;
    }
    if (index < arr.length - 1) {
      index++;
    }
  }
  const point = arr[index];
  return { sog: point.sog, cog: point.cog };
}

export class packData {
  code?:number;
  msg?:string;
  message?:string;
  data?:{
    download_url: string;
    size:number;
  }
}

export class diyPointsData {
  paths: [number,number,boolean][];
}

/** 打包任务数据 */
export async function getTaskPack(data) {
  const res = await axios({
    method: 'post',
    url: `/task/pack`,
    data
  });
  return res.data as packData;
}


/** 导入打包的任务数据 */
export async function impTaskPack(data) {
  const res = await axios({
    method: 'post',
    url: `/task/unpack`,
    data
  });
  return res.data.data as packData;
}

/** 导入自定义航线数据 */
export async function impDiyPoints(data) {
  const res = await axios({
    method: 'post',
    url: `/task/upload`,
    data
  });
  return res.data.data as diyPointsData;
}


/** 获取八个方向姿态预测曲线 */
export async function getEightDirPose(params) {
  const res = await axios({
    method: 'get',
    url: `/pose/eight/angle`,
    params
  });
  return res.data.data;
}
